package com.gogant.spider.core;

import com.gogant.spider.util.StringUtils;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public class PickerConfigurer {
	private List<Matcher> matcherList = new ArrayList<Matcher>();
	private URLPicker<?> urlPicker;

	public PickerConfigurer(URLPicker<? extends Response> urlPicker) {
		this.urlPicker = urlPicker;
	}

	protected URLPicker<?> getURLPicker() {
		return urlPicker;
	}

	protected Matcher findMatcher(URL url) {
		if (matcherList.size() == 0) {
			return null;
		}
		String urlStr = url.toString();
		for (Matcher matcher : matcherList) {
			if (matcher.patterns == null || matcher.patterns.length == 0) {
				return matcher;
			}
			for (Pattern pattern : matcher.patterns) {
				if (pattern.matcher(urlStr).find()) {
					return matcher;
				}
			}
		}
		return null;
	}

	/**
	 * 当URL满足条件中的任意一个正则表达式时，触发提取URL
	 *
	 * @param regexps
	 * @return
	 */
	public Matcher when(String... regexps) {
		Pattern[] patterns = new Pattern[regexps.length];
		for (int i = 0; i < regexps.length; i++) {
			patterns[i] = Pattern.compile(regexps[i]);
		}
		Matcher matcher = new Matcher(patterns);
		matcherList.add(matcher);
		return matcher;
	}

	public class Matcher {
		Pattern[] patterns;
		List<String> containKeywords = new ArrayList<String>();
		List<String> likePatterns = new ArrayList<String>();
		List<Pattern> matchesPatterns = new ArrayList<Pattern>();
		List<Pattern> findPatterns = new ArrayList<Pattern>();

		public Matcher(Pattern[] patterns) {
			this.patterns = patterns;
		}

		protected boolean isAccept(URL url) {
			if (url.getRef() != null) {
				return false;
			}
			String urlStr = url.toString();
			for (String keyword : containKeywords) {
				if (urlStr.contains(keyword)) {
					return true;
				}
			}
			for (String ptn : likePatterns) {
				if (StringUtils.isLike(urlStr, ptn)) {
					return true;
				}
			}
			for (Pattern ptn : matchesPatterns) {
				if (ptn.matcher(urlStr).matches()) {
					return true;
				}
			}
			for (Pattern ptn : findPatterns) {
				if (ptn.matcher(urlStr).find()) {
					return true;
				}
			}
			return false;
		}

		/**
		 * 关键字匹配，如果URL中包含条件中的任意一个关键字，则匹配成功
		 *
		 * @param keywords
		 * @return
		 */
		public PickerConfigurer contains(String... keywords) {
			for (String keyword : keywords) {
				containKeywords.add(keyword);
			}
			return PickerConfigurer.this;
		}

		/**
		 * 根据模式匹配，如果URL满足中的任意一个模式，则匹配成功，模式与SQL like功能一样，例如：%/aaa.html
		 *
		 * @param patterns
		 * @return
		 */
		public PickerConfigurer like(String... patterns) {
			for (String pattern : patterns) {
				likePatterns.add(pattern);
			}
			return PickerConfigurer.this;
		}

		/**
		 * 正则表达式匹配，如果URL完全匹配条件中的任意一个正则表达式，则匹配成功，详情见Java正则表达式：Matcher:matches
		 *
		 * @param regexps
		 * @return
		 */
		public PickerConfigurer matches(String... regexps) {
			for (String regexp : regexps) {
				matchesPatterns.add(Pattern.compile(regexp));
			}
			return PickerConfigurer.this;
		}

		/**
		 * 正则表达式匹配，如果URL满足条件中的任意一个正则表达式，则匹配成功，详情见Java正则表达式：Matcher:find
		 *
		 * @param regexps
		 * @return
		 */
		public PickerConfigurer find(String... regexps) {
			for (String regexp : regexps) {
				findPatterns.add(Pattern.compile(regexp));
			}
			return PickerConfigurer.this;
		}
	}
}
